﻿

#region Using Statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Threading;
using System.ComponentModel;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Design;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using Freeform;
using FGame = Freeform.Game;
using XGame = Microsoft.Xna.Framework.Game;
using FComponent = Freeform.Component;

#endregion


namespace Freeform
{
    /// <summary>
    /// An component list is a datastructure used to access a list of components.
    /// </summary>
    public class ComponentList
    {

        #region Members

        /// <summary>
        /// Gets or sets the underlying data structure used by the entity list.
        /// </summary>
        internal Dictionary<UInt64, Component> Library { get; set; }


        /// <summary>
        /// Gets a list of all entities in the list.
        /// </summary>
        public List<Component> All { get; private set; }


        /// <summary>
        /// Gets a list of all loaded entities in the list.
        /// </summary>
        public List<Component> Loaded { get; private set; }


        /// <summary>
        /// Gets a list of all unloaded entities in the list.
        /// </summary>
        public List<Component> Unloaded { get; private set; }


        /// <summary>
        /// Gets or sets whether the elements of the list should be sorted based on priority.
        /// </summary>
        public Boolean PrioritySorting { get; set; }


        /// <summary>
        /// Gets a reference to the game that this ComponentList belongs to.
        /// </summary>
        public IGame Game { get; private set; }

        #endregion


        #region Init

        /// <summary>
        /// Creates a new entity list.
        /// </summary>
        public ComponentList(IGame Game)
        {
            this.Game = Game;
            Library = new Dictionary<UInt64, Component>();
            All = new List<Component>();
            Loaded = new List<Component>();
            Unloaded = new List<Component>();
        }

        #endregion


        #region Update

        /// <summary>
        /// Updates all the entity lists from the underlying data structure.
        /// </summary>
        public virtual void UpdateLists()
        {
            // Load all entities into the All list.
            All = Library.Values.ToList();

            // Clear all other lists.
            Loaded.Clear();
            Unloaded.Clear();

            // Sort list if necessary.
            if (PrioritySorting)
                All.Sort(ComparePriority);

            // Setup other lists.
            for (int i = 0; i < All.Count; i++)
            {
                if (All[i].IsLoaded)
                    Loaded.Add(All[i]);
                else
                    Unloaded.Add(All[i]);
            }
        }

        #endregion


        #region Implementation

        /// <summary>
        /// This function is the comparer used to sort the components via their priority.
        /// </summary>
        /// <param name="A">Component A.</param>
        /// <param name="B">Component B.</param>
        /// <returns></returns>
        private Int32 ComparePriority(Component A, Component B)
        {
            if (A.Priority == B.Priority) return 0;
            if (A.Priority > B.Priority) return 1;
            return -1;
        }

        #endregion

    }
}
